<template>
	<view class="star"
		@click="onClick"
		@touchstart="onTouchStart"
		@touchmove="onTouchMove"
		@touchend="onTouchEnd"
		:style="{cursor: props.readonly ? 'default' : 'pointer'}">
		<image :style="[widthVar,heightVar]" src="http://www.xvopen.com/xiaoV/img1/star-grey.png" mode=""></image>
		<view class="star-copy-vessel" :style="{width: (props.width ? (localStarRate/5*parseInt(props.width.replace('rpx',''))+'rpx') : (localStarRate/5*140+'rpx'))}">
			<view class="star-copy" :style="[widthVar,heightVar]">
				<image src="http://www.xvopen.com/xiaoV/img1/star.png" mode=""></image>
			</view>
		</view>
	</view>
</template>

<script setup>
	import {ref,onMounted,watch} from "vue";
	let props = defineProps({
		width: {
			type: String,
		},
		height: {
			type: String,
			default:function(){
				return '24rpx'
			}
		},
		starRate: {//传入评分星级 1 2 3 4 5
			type: Number,
			default: 0
		},
		readonly: {
			type: Boolean,
			default: true
		}
	})

	let widthVar = ref("--width: 140rpx")
	let heightVar = ref("--height: 24rpx")
	let vesselWidthStr = ref("")
	let localStarRate = ref(props.starRate)
	let isTouching = ref(false)

	watch(() => props.starRate, (newVal) => {
		localStarRate.value = newVal
		if (props.width) {
			vesselWidthStr.value = newVal / 5 * parseInt(props.width.replace('rpx', '')) + 'rpx'
		} else {
			vesselWidthStr.value = newVal / 5 * 140 + 'rpx'
		}
	}, {immediate: true})

	function getRateByEvent(e) {
		let x = 0;
		let rect, width;
		// 统一用 currentTarget 获取 rect，防止 undefined
		if (typeof window !== 'undefined' && e.touches && e.touches[0]) {
			x = e.touches[0].clientX;
			rect = e.currentTarget.getBoundingClientRect();
		} else if (typeof window !== 'undefined' && e.clientX) {
			x = e.clientX;
			rect = e.currentTarget.getBoundingClientRect();
		} else if (e.touches && e.touches[0]) { // 小程序
			x = e.touches[0].pageX;
			if (e.currentTarget && e.currentTarget.getBoundingClientRect) {
				rect = e.currentTarget.getBoundingClientRect();
			} else {
				// fallback，防止rect为undefined
				rect = {left: 0};
			}
		} else {
			rect = {left: 0};
		}
		width = props.width ? parseInt(props.width.replace('rpx', '')) : 140;
		let offsetX = x - rect.left;
		let rate = Math.ceil(offsetX / (width / 5));
		if (offsetX <= 0) rate = 0;
		if (offsetX >= width) rate = 5;
		if (rate < 0) rate = 0;
		if (rate > 5) rate = 5;
		return rate;
	}

	function onTouchStart(e) {
		if (props.readonly) return;
		isTouching.value = true;
	}

	function onTouchMove(e) {
		if (props.readonly || !isTouching.value) return;
		localStarRate.value = getRateByEvent(e);
	}

	function onTouchEnd(e) {
		if (props.readonly) return;
		isTouching.value = false;
		localStarRate.value = getRateByEvent(e);
		emits('update:starRate', localStarRate.value);
	}

	function onClick(e) {
		if (props.readonly) return;
		localStarRate.value = getRateByEvent(e);
		emits('update:starRate', localStarRate.value);
	}

	onMounted(() => {
		if (props.width) {
			widthVar.value = '--width:' + props.width
		}
		if (props.height) {
			heightVar.value = '--height:' + props.height
		}
	})

	const emits = defineEmits(['click', 'update:starRate'])
	// const onClick = () => {
	// 	emits('click')
	// }

</script>

<style scoped lang="scss">
.star{
	position: relative;
	image{
		width: var(--width);
		height: var(--height);
	}
	.star-copy-vessel{
		height: 100%;
		position: absolute;
		top: 0;
		left: 0;
		overflow: hidden;
		.star-copy{
			width: var(--width);
			position: absolute;
			top: 0;
			left: 0;
		}
	}
}
</style>
